﻿// GameDll.cpp: 定义 DLL 的初始化例程。
//

#include "pch.h"
#include "framework.h"
#include "GameDll.h"
#include "DialgWgMain.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


#ifdef BUILDING_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif

// CGameDllApp

BEGIN_MESSAGE_MAP(CGameDllApp, CWinApp)
END_MESSAGE_MAP()


// CGameDllApp 构造

CGameDllApp::CGameDllApp()
{
	// TODO:  在此处添加构造代码，
	// 将所有重要的初始化放置在 InitInstance 中
}


// 唯一的 CGameDllApp 对象

CGameDllApp theApp;
DialgWgMain *dialogMain;

HWND gameHwnd; //游戏的hwnd
CString gameName; //游戏的角色名称

DWORD gameThreadId;
bool isFristCreat;

// CGameDllApp 初始化

BOOL CGameDllApp::InitInstance()
{
	CWinApp::InitInstance();

	return TRUE;
}

ReadResult readCheck(int dwProcessId) {
    ReadResult re;
    long tempAdress = 0; 
    long *ptempAdress = 0; 
    SIZE_T* readByte = NULL;
    HANDLE hProcess = ::OpenProcess(PROCESS_VM_READ, false, dwProcessId);
    if (hProcess == NULL) {
        re.isSuccess = false;
        re.reason.Format(L"获取hProcess失败");
        return re;
    }
    ReadProcessMemory(hProcess, (LPVOID)(GAME_BASE), &tempAdress, 4, readByte);//一级地址读取
    if (tempAdress == NULL || tempAdress < 0x00DBB000 || tempAdress >0x00ED7FFE) {
        re.isSuccess = false;
        re.reason.Format(L"获取一级地址读取失败,其值为：%d", tempAdress);
        return re;
    }


    ReadProcessMemory(hProcess, (LPVOID)(tempAdress + GAME_BASE_P1), &tempAdress, 4, readByte);//一级地址读取后偏移地址值读取后偏移读取二级地址值
    if (tempAdress == NULL || tempAdress < 0x033B0000 || tempAdress >0x040AEFFE) {
        re.isSuccess = false;
        re.reason.Format(L"获取一级地址读取后偏移地址值读取后偏移读取二级地址值失败,其值为：%d", tempAdress);
        return re;
    }

    ReadProcessMemory(hProcess, (LPVOID)(tempAdress + GAME_BASE_P2), &tempAdress, 4, readByte);//一级地址读取后偏移地址值读取后偏移读取二级地址值

    if (tempAdress == NULL || tempAdress < 0x10000000 || tempAdress >0x75000000) {
        re.isSuccess = false;
        re.reason.Format(L"获取人物基指失败,其值为：%d", tempAdress);
        return re;
    }

    re.isSuccess = true;
    re.reason.Format(L"获取人物基指成功");
    re.data = tempAdress;
    return re;
}


LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    if (nCode == HC_ACTION) {
        OutputDebugStringA("监听到HOME按下了\n");
        KBDLLHOOKSTRUCT* kbs = (KBDLLHOOKSTRUCT*)lParam;
        if (wParam == VK_HOME && ((lParam&(1<<31)) == 0)) {
            OutputDebugStringA("监听到HOME按下了");
            //MessageBoxA(NULL, "监听到了", "监听到HOME按下了", MB_USERICON | MB_OK);
            if (dialogMain == NULL) {
                isFristCreat = true;
                int crrentProcessId = GetCurrentProcessId();
                DWORD dwBaseL1L2 = 0;
                DWORD nameStr = 0;
                DWORD VipRealLevel = 0;
                ReadResult re = readCheck(crrentProcessId);

                if (!re.isSuccess) {
                    MessageBox(NULL, re.reason, L"读取检测失败，需要升级基指或者游戏没登录", MB_OK);
                    return CallNextHookEx(NULL, nCode, wParam, lParam);
                }
                dialogMain = new DialgWgMain;
                dialogMain->Create(IDD_DIALOG_WG_MAIN);
                __asm {
                    mov	esi, GAME_BASE
                    mov esi, [esi]
                    mov	esi, [esi + GAME_BASE_P1]
                    mov esi, [esi + GAME_BASE_P2]
                    mov ecx, [esi + GAME_INFO_MAN_OFFSET_NAME]
                    mov [nameStr], ecx
                    mov ecx, [esi + GAME_INFO_MAN_VIP_LEVEL]
                    mov VipRealLevel, ecx
              
                }
                CString NameW;
                dialogMain->VIPRealLevel = VipRealLevel;
                dialogMain->m_dwProcessId = crrentProcessId;
                NameW.Format(L"%s  vip:%d ,pid:%d", nameStr, VipRealLevel, crrentProcessId); // 设置游戏名称为WG窗口名称
                //MessageBox(NULL, L"监听到了", NameW, MB_USERICON | MB_OK);
                dialogMain->SetWindowText(NameW);
                CString vipText;
                vipText.Format(L"%d", VipRealLevel);
                dialogMain->editVIP->SetWindowTextW(vipText);
           
            }

            if (dialogMain->IsWindowVisible()) {
                dialogMain->ShowWindow(SW_HIDE);
            }
            else
            {
                dialogMain->ShowWindow(SW_SHOW);
                if (isFristCreat) {
                    RECT rect = { 0, 189, 260, 591 }; // 设置位置和大小
                    dialogMain->GetWindowRect(&rect);
                    int width = abs(rect.right - rect.left);
                    rect.left = rect.left - width;
                    rect.right = rect.right - width;
                    dialogMain->MoveWindow(&rect); // 移动窗口到指定位置和大小
                    isFristCreat = false;
                }
            }
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

HHOOK keyboardHook;


void setHook(int hWnd, CString gametitle) {
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
         gameHwnd = (HWND)hWnd;
        if (gameHwnd == NULL) {
            MessageBoxA(NULL, "没找到", "窗口没找到", MB_ICONERROR | MB_OK);
            return;
        }

        gameName = gametitle;
        OutputDebugString(gameName);
        OutputDebugStringA("\n");
        OutputDebugStringA("窗口找到了\n");
        gameThreadId= ::GetWindowThreadProcessId(gameHwnd,NULL);
        if (gameThreadId == NULL) {
            MessageBoxA(NULL, "错误", "获取线程失败", MB_ICONERROR|MB_OK);
            return;
        }
        OutputDebugStringA("获取线程获取到线程!\n");
        keyboardHook = SetWindowsHookEx(WH_KEYBOARD, &KeyboardProc, ::GetModuleHandleA("GameDll.dll"), gameThreadId);
        if (keyboardHook == NULL) {
            MessageBoxA(NULL, "错误", "Hook failed", MB_ICONERROR | MB_OK);
            OutputDebugStringA("Hook failed!\n");
            return;
        }
        OutputDebugStringA("设置了Hook!\n");
}

void unHook() {
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    UnhookWindowsHookEx(keyboardHook);
}

int CGameDllApp::ExitInstance()
{
    unHook();
    if (dialogMain != NULL) {
        delete dialogMain;
        dialogMain = NULL;
    }
    return  CWinApp::ExitInstance();
}